using Gtk;
using System;
using System.Collections;
using System.Reflection;
using System.Data;

using NHibernate;
using NHibernate.Tool;   //????

namespace Serpis
{
	internal class ComboBoxHelper
	{
		private ISession session;
		private ComboBox comboBox;
		private ListStore listStore;
		private PropertyInfo propertyInfo;
		private Type type;
		
		// Manejador de eventos Changed...
		public event EventHandler Changed;
		
		public ComboBoxHelper (ComboBox comboBox, ISessionFactory sessionFactory, Type type)
		{
			session= sessionFactory.OpenSession();
			
			this.comboBox = comboBox;
			this.type= type;
		}
		
		public object CurrentItem 
		{
			get
			{
				if (listStore == null) 
				{
					init(null);
				}
				TreeIter treeIter;
				comboBox.GetActiveIter(out treeIter);
				return listStore.GetValue(treeIter, 0);
			}
			
			set 
			{
				if (listStore == null)
				{
					init(value);
				}
				else 
				{
					TreeIter treeIter;
					if (!listStore.GetIterFirst(out treeIter))
					{
						return;
					}
					do 
					{
						if (value == listStore.GetValue(treeIter, 0)) 
						{
							comboBox.SetActiveIter(treeIter);
							break;
						}
					} while (listStore.IterNext(ref treeIter));
				}
			}
		}
		
		private void init(object item)
		{
			CellRendererText cellRenderer = new CellRendererText();
			comboBox.PackStart(cellRenderer, true);
			comboBox.SetCellDataFunc(cellRenderer, cellLayoutDataFunc);
			
			listStore = new ListStore(typeof(object));
			
			foreach(PropertyInfo property in type.GetProperties()) 
			{
				if(property.IsDefined(typeof(ComboBoxView), true)) 
				{
					propertyInfo= property;
					break;
				}
			}
			
			IQuery query= session.CreateQuery("from "+type.Name);
			IList list= query.List();
			IEnumerator enumerator= list.GetEnumerator();
			
			string primaryKey= "";
			foreach(PropertyInfo property in type.GetProperties()) 
			{
				if(property.IsDefined(typeof(ComboBoxPK), true)) 
				{
					primaryKey= property.Name;
					break;
				}
			}
			PropertyInfo PKProperty= type.GetProperty(primaryKey);
			
			object current= System.Activator.CreateInstance(type);
			propertyInfo.SetValue(current, "<VACÍO>", null);
			TreeIter treeIter= listStore.AppendValues(current);
			
			while(enumerator.MoveNext()) 
			{
				object obj= enumerator.Current;
				TreeIter currentTreeIter = listStore.AppendValues(obj);
				
				if(item != null && PKProperty.GetValue(obj, null).Equals(PKProperty.GetValue(item, null)))
				{
					treeIter= currentTreeIter;
				}
			}
			
			session.Close();
			comboBox.Model = listStore;		
			comboBox.SetActiveIter(treeIter);
			
			//	Nos susribimos
			comboBox.Changed += delegate 
			{
				raiseChanged();				
			};
		}
		
		private void cellLayoutDataFunc(CellLayout cell_layout, CellRenderer cell, TreeModel tree_model, TreeIter iter) 
		{
			CellRendererText cellRendererText= (CellRendererText)cell;
			object obj= tree_model.GetValue(iter, 0);
			object value= propertyInfo.GetValue(obj, null);
			cellRendererText.Text= value.ToString();
		}
		
		//	Evento
		private void raiseChanged()
		{
			if (Changed != null)
				Changed(this, EventArgs.Empty);
		}
		
		
	}
}
